/**
 * 获取对象的key 在拼接Change字符。得到新的字面量类型
 * {
 *    name: "chen"
 * }
 * ===>>> "nameChange"
 */

/**
 * & 符号 条件关系。
 * string & keyof T 只保留其中的string类型
 */
type ObjectKeyString<T extends Record<string, any>> = `${string &
  keyof T}Change`;
type ObjectKey<T extends Record<string, any>> = keyof T; // 获取 key值 可能是 string | number | symbol

const sy = Symbol("name");
const obj = {
  [sy]: "name",
  name: "chen",
  [1]: 10,
};
type Key1 = ObjectKey<typeof obj>; // "name" | typeof sy | 1
type KeyString1 = ObjectKeyString<typeof obj>; // "nameChange"

// 实用案列 类型推倒
type Watcher<T> = {
  on<K extends string & keyof T>(
    eventName: `${K}Change`, // ===>>> keyof T 可能是 string | symbol | number; 这里用string约束 使其是string类型
    callback: (oldValue: T[K], newValue: T[K]) => void
  ): void;
};
declare function watch<T>(obj: T): Watcher<T>;

const personWatcher = watch({
  name: "chen",
  age: 20,
});
// 对name属性进行监听
personWatcher.on("nameChange", (oldValue, newValue) => {});

export {};
